// License text copyright (c) 2020 MariaDB Corporation Ab, All Rights Reserved.
// "Business Source License" is a trademark of MariaDB Corporation Ab.

// Parameters

// Licensor:             Union.fi, Labs Inc.
// Licensed Work:        All files under https://github.com/unionlabs/union's sui subdirectory
//                       The Licensed Work is (c) 2024 Union.fi, Labs Inc.
// Change Date:          Four years from the date the Licensed Work is published.
// Change License:       Apache-2.0
//

// For information about alternative licensing arrangements for the Licensed Work,
// please contact info@union.build.

// Notice

// Business Source License 1.1

// Terms

// The Licensor hereby grants you the right to copy, modify, create derivative
// works, redistribute, and make non-production use of the Licensed Work. The
// Licensor may make an Additional Use Grant, above, permitting limited production use.

// Effective on the Change Date, or the fourth anniversary of the first publicly
// available distribution of a specific version of the Licensed Work under this
// License, whichever comes first, the Licensor hereby grants you rights under
// the terms of the Change License, and the rights granted in the paragraph
// above terminate.

// If your use of the Licensed Work does not comply with the requirements
// currently in effect as described in this License, you must purchase a
// commercial license from the Licensor, its affiliated entities, or authorized
// resellers, or you must refrain from using the Licensed Work.

// All copies of the original and modified Licensed Work, and derivative works
// of the Licensed Work, are subject to this License. This License applies
// separately for each version of the Licensed Work and the Change Date may vary
// for each version of the Licensed Work released by Licensor.

// You must conspicuously display this License on each original or modified copy
// of the Licensed Work. If you receive the Licensed Work in original or
// modified form from a third party, the terms and conditions set forth in this
// License apply to your use of that work.

// Any use of the Licensed Work in violation of this License will automatically
// terminate your rights under this License for the current and all other
// versions of the Licensed Work.

// This License does not grant you any right in any trademark or logo of
// Licensor or its affiliates (provided that you may use a trademark or logo of
// Licensor as expressly required by this License).

// TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
// AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
// EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
// TITLE.

module ibc::events {
    use sui::event;
    use std::string::String;

    use ibc::packet::Packet;

    // This event is only emitted during the `init` phase
    // since the voyager event source module requires at least
    // a single event to be emitted to be able to process the
    // events
    public struct Initiated has copy, drop, store {}

    /* ─────────────── CLIENT EVENTS ─────────────── */
    public struct CreateClient has copy, drop, store {
        client_id: u32,
        client_type: String,
        counterparty_chain_id: String
    }

    public struct CreateLensClient has copy, drop, store {
        client_id: u32,
        l2_chain_id: String,
        l1_client_id: u32,
        l2_client_id: u32
    }

    public struct UpdateClient has copy, drop, store {
        client_id: u32,
        height: u64
    }

    public struct Misbehaviour has drop, store, copy {
        client_id: u32
    }

    /* ─────────────── CONNECTION EVENTS ─────────────── */
    public struct ConnectionOpenInit has copy, drop, store {
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32
    }

    public struct ConnectionOpenTry has copy, drop, store {
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    }

    public struct ConnectionOpenAck has copy, drop, store {
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    }

    public struct ConnectionOpenConfirm has copy, drop, store {
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    }

    /* ─────────────── CHANNEL EVENTS ─────────────── */
    public struct ChannelOpenInit has copy, drop, store {
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        connection_id: u32,
        version: String
    }

    public struct ChannelOpenTry has copy, drop, store {
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32,
        counterparty_version: String
    }

    public struct ChannelOpenAck has copy, drop, store {
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32
    }

    public struct ChannelOpenConfirm has copy, drop, store {
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32
    }

    /* ─────────────── PACKET EVENTS ─────────────── */
    public struct PacketSend has drop, copy, store {
        channel_id: u32,
        packet_hash: vector<u8>,
        packet: Packet
    }

    public struct PacketRecv has drop, store, copy {
        channel_id: u32,
        packet_hash: vector<u8>,
        maker: address,
        maker_msg: vector<u8>
    }

    public struct IntentPacketRecv has drop, store, copy {
        channel_id: u32,
        packet_hash: vector<u8>,
        maker: address,
        maker_msg: vector<u8>
    }

    public struct PacketTimeout has drop, store, copy {
        channel_id: u32,
        packet_hash: vector<u8>,
        maker: address
    }

    public struct WriteAck has drop, store, copy {
        channel_id: u32,
        packet_hash: vector<u8>,
        acknowledgement: vector<u8>
    }

    public struct PacketAck has drop, store, copy {
        channel_id: u32,
        packet_hash: vector<u8>,
        acknowledgement: vector<u8>,
        maker: address
    }

    /* ─────────────── EMITTER FUNCTIONS ─────────────── */
    public(package) fun emit_initiated() {
        event::emit(Initiated {})
    }

    /* Client */
    public(package) fun emit_create_client(
        client_id: u32, client_type: String, counterparty_chain_id: String
    ) {
        event::emit(CreateClient { client_id, client_type, counterparty_chain_id })
    }

    public(package) fun emit_create_lens_client(
        client_id: u32,
        l2_chain_id: String,
        l1_client_id: u32,
        l2_client_id: u32
    ) {
        event::emit(
            CreateLensClient { client_id, l2_chain_id, l1_client_id, l2_client_id }
        )
    }

    public(package) fun emit_update_client(client_id: u32, height: u64) {
        event::emit(UpdateClient { client_id, height })
    }

    public(package) fun emit_misbehaviour(client_id: u32) {
        event::emit(Misbehaviour { client_id })
    }

    /* Connection */
    public(package) fun emit_connection_open_init(
        connection_id: u32, client_id: u32, counterparty_client_id: u32
    ) {
        event::emit(
            ConnectionOpenInit { connection_id, client_id, counterparty_client_id }
        )
    }

    public(package) fun emit_connection_open_try(
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    ) {
        event::emit(
            ConnectionOpenTry {
                connection_id,
                client_id,
                counterparty_client_id,
                counterparty_connection_id
            }
        )
    }

    public(package) fun emit_connection_open_ack(
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    ) {
        event::emit(
            ConnectionOpenAck {
                connection_id,
                client_id,
                counterparty_client_id,
                counterparty_connection_id
            }
        )
    }

    public(package) fun emit_connection_open_confirm(
        connection_id: u32,
        client_id: u32,
        counterparty_client_id: u32,
        counterparty_connection_id: u32
    ) {
        event::emit(
            ConnectionOpenConfirm {
                connection_id,
                client_id,
                counterparty_client_id,
                counterparty_connection_id
            }
        )
    }

    /* Channel */
    public(package) fun emit_channel_open_init(
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        connection_id: u32,
        version: String
    ) {
        event::emit(
            ChannelOpenInit {
                port_id,
                channel_id,
                counterparty_port_id,
                connection_id,
                version
            }
        )
    }

    public(package) fun emit_channel_open_try(
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32,
        counterparty_version: String
    ) {
        event::emit(
            ChannelOpenTry {
                port_id,
                channel_id,
                counterparty_port_id,
                counterparty_channel_id,
                connection_id,
                counterparty_version
            }
        )
    }

    public(package) fun emit_channel_open_ack(
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32
    ) {
        event::emit(
            ChannelOpenAck {
                port_id,
                channel_id,
                counterparty_port_id,
                counterparty_channel_id,
                connection_id
            }
        )
    }

    public(package) fun emit_channel_open_confirm(
        port_id: address,
        channel_id: u32,
        counterparty_port_id: vector<u8>,
        counterparty_channel_id: u32,
        connection_id: u32
    ) {
        event::emit(
            ChannelOpenConfirm {
                port_id,
                channel_id,
                counterparty_port_id,
                counterparty_channel_id,
                connection_id
            }
        )
    }

    /* Packet */
    public(package) fun emit_packet_send(
        channel_id: u32, packet_hash: vector<u8>, packet: Packet
    ) {
        event::emit(PacketSend { channel_id, packet_hash, packet })
    }

    public(package) fun emit_packet_recv(
        channel_id: u32,
        packet_hash: vector<u8>,
        maker: address,
        maker_msg: vector<u8>
    ) {
        event::emit(
            PacketRecv { channel_id, packet_hash, maker, maker_msg }
        )
    }

    public(package) fun emit_intent_packet_recv(
        channel_id: u32,
        packet_hash: vector<u8>,
        maker: address,
        maker_msg: vector<u8>
    ) {
        event::emit(
            IntentPacketRecv { channel_id, packet_hash, maker, maker_msg }
        )
    }

    public(package) fun emit_packet_timeout(
        channel_id: u32, packet_hash: vector<u8>, maker: address
    ) {
        event::emit(PacketTimeout { channel_id, packet_hash, maker })
    }

    public(package) fun emit_write_ack(
        channel_id: u32, packet_hash: vector<u8>, acknowledgement: vector<u8>
    ) {
        event::emit(WriteAck { channel_id, packet_hash, acknowledgement })
    }

    public(package) fun emit_packet_ack(
        channel_id: u32,
        packet_hash: vector<u8>,
        acknowledgement: vector<u8>,
        maker: address
    ) {
        event::emit(
            PacketAck { channel_id, packet_hash, acknowledgement, maker }
        )
    }
}
